package cn.xiaobai.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.xiaobai.utils.TimeUtils;
import cn.xioabai.common.utility.IOUtils;
import cn.xioabai.common.utility.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author
 * @date 2020/7/30 8:54
 * 判断当前是否为节假日： 0 上班 1周末 2节假日
 */
@Slf4j
@Service
public class HolidayService {

    @Value("${url.holiday}")
    private String holidayUrl;

    /**
     * 节假日Map, key: 日期, value: 是否是节假日,true:是节假日
     */
    private static Map<String, Boolean> dateToHolidayMap = new HashMap<>();

    /**
     * 获取节假日并缓存, 根据指定日期获取节假日
     *
     * @param date        日期
     * @param holidayPath 节假日配置文件
     * @return
     */
    public Boolean getHolidayToMapByDate(String date, String holidayPath) {
        String readConfig = IOUtils.readerFileToString(holidayPath);
        // 将当前月份补零修正
        String revisionDate = TimeUtils.revisionDateZone(date);
        if (StringUtils.isNoneBlank(readConfig)) {
            // 存在该文件, 则进行读取
            dateToHolidayMap = JsonUtils.readValue(readConfig, new TypeReference<Map<String, Boolean>>() {
            });
            // 文件不为空时进行操作
            if (CollectionUtil.isNotEmpty(dateToHolidayMap)) {
                if (dateToHolidayMap.containsKey(revisionDate)) {
                    return dateToHolidayMap.get(revisionDate);
                }
            }
        }
        dateToHolidayMap.clear();
        // 当文件不存在或者该日期不存在时, 则进行请求缓存
        log.info("缓存文件读取失败或缓存文件过期, 开始缓存一个月的日期");
        initCache(holidayPath);
        return dateToHolidayMap.get(revisionDate);
    }

    /**
     * 获取节假日并缓存, 根据指定日期获取节假日
     *
     * @return
     */
    private void initCache( String holidayPath) {
        // 获取当年的第一天
        Date yearFirstDay = TimeUtils.getYearFirstDay();
        // 获取当年的最后一天
        int yearLastInt = TimeUtils.getYearLastInt();
        // 循环请求获取一个月的节假日
        List<String> data = new ArrayList<>();
        for (int i = 0; i < yearLastInt; i++) {
            Date calcul = TimeUtils.dateCalcul(yearFirstDay, i);
            String dateToString = TimeUtils.dateToString(calcul);
            data.add(dateToString);
        }
        String dateList = Strings.join(data, ',');
        // 批量获取节假日状态
        request(dateList);

        log.info("将一个月的缓存数据保存到文件中");
        String jsonStr = JsonUtils.toJsonStr(dateToHolidayMap);
        IOUtils.dataWriteFile(jsonStr, holidayPath);
    }


    /**
     * 判断当前是否为节假日： 0 上班 1周末 2节假日
     *
     * @param httpArg :参数
     * @return 返回结果
     */
    public String request(String httpArg) {
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        String toolUrl = holidayUrl + "?d=" + httpArg;
        try {
            URL url = new URL(toolUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
            String strRead;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
            }
            reader.close();
            result = sbf.toString();
            strDateToBool(result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 字符串转换为boolean
     * 这里将节假日的表示转换为true, 否则 false
     *
     * @param string 数字类型字符串
     * @return
     */
    public void strDateToBool(String string) {
        Map<String, String> stringStringMap = JsonUtils.readValue(string,
                new TypeReference<Map<String, String>>() {
                });

        stringStringMap.forEach((k, v) -> {
            dateToHolidayMap.put(k, "1".equals(v) || "2".equals(v));
        });


//        boolean isHoliday = false;
//        // 1: 周末, 2: 节假日
//        if ("1".equals(string) || "2".equals(string)) {
//            isHoliday = true;
//            //当前日期为节假日日期
//        }
//
//        // 0: 上班
//        if ("0".equals(string)) {
//            // isHoliday = false;
//            //当前日期为上班日期
//        }
//        return isHoliday;
    }

}

